package main

import (
	"fmt"
	"math/rand"
	"sort"
)

func main() {
	// 1、看下面一段程序，回答问题
	// s1 := make([]int, 3, 4)
	// s2 := append(s1, 1)

	// 问1：s1、s2内各有什么元素？
	// s1 里面有 []int[0 0 0], 长度为3，容量为4
	// s2 里面有 []int[0 0 0 1], 长度为4，容量为4
	// 代码验证：
	// fmt.Printf("s1元素:%v\ns1长度:%d\ns1容量:%d\n", s1, len(s1), cap(s1))
	// fmt.Printf("s2元素:%v\ns1长度:%d\ns1容量:%d\n", s2, len(s2), cap(s2))
	// fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")

	// 问2：s1修改一个元素会影响s2吗？s2修改一个元素会影响s1么？
	// s1、s2共用底层数组，s1修改一个元素，将会对s2产生影响。
	// s2 修改第0,1,2个元素时会对s1产生影响，修改第3个元素时，不会对s1产生影响。
	// 代码验证：
	// 对s1内元素进行修改
	// fmt.Println("分别修改s1的第0、1、2个元素")
	// s1[0] = 1
	// fmt.Printf("s1元素:%v\ns1长度:%d\ns1容量:%d\n", s1, len(s1), cap(s1))
	// fmt.Printf("s2元素:%v\ns1长度:%d\ns1容量:%d\n", s2, len(s2), cap(s2))
	// s1[1] = 1
	// fmt.Printf("s1元素:%v\ns1长度:%d\ns1容量:%d\n", s1, len(s1), cap(s1))
	// fmt.Printf("s2元素:%v\ns1长度:%d\ns1容量:%d\n", s2, len(s2), cap(s2))
	// s1[2] = 1
	// fmt.Printf("s1元素:%v\ns1长度:%d\ns1容量:%d\n", s1, len(s1), cap(s1))
	// fmt.Printf("s2元素:%v\ns1长度:%d\ns1容量:%d\n", s2, len(s2), cap(s2))
	// fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
	// fmt.Println("分别修改s2的第0、1、2、3个元素")
	// s2[0] = 0
	// fmt.Printf("s1元素:%v\ns1长度:%d\ns1容量:%d\n", s1, len(s1), cap(s1))
	// fmt.Printf("s2元素:%v\ns1长度:%d\ns1容量:%d\n", s2, len(s2), cap(s2))
	// s2[1] = 0
	// fmt.Printf("s1元素:%v\ns1长度:%d\ns1容量:%d\n", s1, len(s1), cap(s1))
	// fmt.Printf("s2元素:%v\ns1长度:%d\ns1容量:%d\n", s2, len(s2), cap(s2))
	// s2[2] = 0
	// fmt.Printf("s1元素:%v\ns1长度:%d\ns1容量:%d\n", s1, len(s1), cap(s1))
	// fmt.Printf("s2元素:%v\ns1长度:%d\ns1容量:%d\n", s2, len(s2), cap(s2))
	// s2[3] = 3
	// fmt.Printf("s1元素:%v\ns1长度:%d\ns1容量:%d\n", s1, len(s1), cap(s1))
	// fmt.Printf("s2元素:%v\ns1长度:%d\ns1容量:%d\n", s2, len(s2), cap(s2))

	// 问3：s2再增加一个元素会怎么样？
	// 当前s1和s2还共用同一个底层切片，s2切片的len为4、cap为4，底层切片的cap为4。
	// s2再增加一个元素底层切片cap将被撑爆，底层数组将被复制生成一个全新的数组。
	// 如当前s2内的元素有[]int[0 0 0 3]，再追加1个元素如2后，s2的元素为[]int[0 0 0 3 2]，
	// 此时s1与s2底层数组将不再是同一个。
	// 代码验证：
	// fmt.Println("s2未新增前,底层数组s1和s2的内存地址")
	// fmt.Printf("s1内存地址:%p 第一个元素的地址:%p\n", &s1, &s1[0])
	// fmt.Printf("s2内存地址:%p 第一个元素的地址:%p\n", &s2, &s2[0])
	// fmt.Println("s2新增一个元素,底层数组s1和s2的内存地址")
	// s2 = append(s2, 2)
	// fmt.Println("s1内的元素", s1)
	// fmt.Println("s2内的元素", s2)
	// fmt.Printf("s1内存地址:%p 第一个元素的地址:%p\n", &s1, &s1[0])
	// fmt.Printf("s2内存地址:%p 第一个元素的地址:%p\n", &s2, &s2[0])

	// 2、有一个数组 [1,4,9,16,2,5,10,15]，生成一个新切片，要求新切片元素是数组相邻2项的和。
	s := [...]int{1, 4, 9, 16, 2, 5, 10, 15}
	ns := make([]int, 0, 6)

	for i := 0; i < (len(s) - 1); i++ {
		ns = append(ns, s[i]+s[i+1])
	}
	fmt.Println(ns)

	// 3、数字重复统计
	// 随机产生100个整数
	// 数字的范围[-100, 100]
	// 降序输出这些生成的数字并打印其重复的次数
	s1 := make([]int, 0, 100)
	for i := 0; i <= 100; i++ {
		s1 = append(s1, (rand.Intn(200) - 100))
	}
	//从小到大顺序
	// sort.Sort(sort.IntSlice(s1))
	// sort.Ints(s1)
	fmt.Println(s1)
	sort.Sort(sort.Reverse(sort.IntSlice(s1)))
	fmt.Println(s1)

	// 4、简述线性数据结构和哈希表优劣
	//线性数据结构是顺序的
}
// 批改意见
// 1. 未统计数字的重复次数
